package cn.senjoeson.timedowner.dao;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.support.annotation.NonNull;
import android.util.Log;

import java.util.ArrayList;
import java.util.List;

/**
 * @author Android
 * @date 2017/12/25
 */

/**
 * define every the primary key of table is the first column
 *
 * @param <UseDefine>
 */
public abstract class BaseDao<UseDefine> {


    private static final String TAG = "BaseDao";
    private SQLiteDatabase mWritableDatabase;
    private SQLiteDatabase mReadableDatabase;
    private DBHelper dbHelper;

    private String TABLE_NAME;

    /**
     * 选取一个唯一的字段
     */
    private String UNIQUE_FEILD;

    /**
     * @param context    上下文
     * @param TABLE_NAME 表名
     */
    public BaseDao(Context context, String TABLE_NAME) {
        String SQL_CREATE_TABLE = createTableExce();
        dbHelper = new DBHelper(context, SQL_CREATE_TABLE);
        mWritableDatabase = dbHelper.getWritableDatabase();
        mReadableDatabase = dbHelper.getReadableDatabase();
        this.TABLE_NAME = TABLE_NAME;
        UNIQUE_FEILD = setUniqueField();
    }


    /**
     * 创建表结构
     *
     * @return 返回执行语句
     */
    protected abstract String createTableExce();


    /**
     * 因为无法知道一张表有多少个列数，无法知道列数的设置是什么类型，用抽象方法让自子类去实现
     * 每个都默认定义第一列为primary key 所以index从 1开始
     *
     * @param cursor 从cursor中可以获得每个列中的数据
     */
    public abstract UseDefine getSingleData(Cursor cursor);

    /**
     * 设置一个唯一字段，每次方便数据库操作
     *
     * @return
     */
    protected abstract String setUniqueField();

    /**
     * 添加一条数据
     *
     * @param contentValues columnName--value 键值对存储
     */
    public boolean addOneData(@NonNull ContentValues contentValues) {
        long insert = -1;
        //添加之前查询是否已经存在该条数据
        if (contentValues.containsKey(UNIQUE_FEILD)) {
            //根据唯一值判断是否存在该条数据
            UseDefine useDefine = singleFind(contentValues.get(UNIQUE_FEILD));
            if (useDefine != null) {
                Log.d(TAG, "addOneData: 已经存在该条数据， 无法再次插入相同数据");
            } else {
                insert = mWritableDatabase.insert(TABLE_NAME, null, contentValues);
            }
        }

        return insert > 0;
    }

    /**
     * 统一接口 查询该表中所有的行数据
     *
     * @return 得到所有数据集
     */
    public List<UseDefine> selectAll() {
        Cursor cursor = mReadableDatabase.rawQuery("select * from " + TABLE_NAME, null);
        ArrayList<UseDefine> useDefines = new ArrayList<>();
        if (cursor != null) {
            while (cursor.moveToNext()) {
                UseDefine singleData = getSingleData(cursor);
                useDefines.add(singleData);
            }
            cursor.close();
        }

        return useDefines;
    }


    /**
     * 关闭所有数据库的链接口
     */
    public void closeDB() {
        if (mWritableDatabase != null) {

            mWritableDatabase.close();
            mWritableDatabase = null;
        }
        if (mReadableDatabase != null) {
            mReadableDatabase.close();
            mReadableDatabase = null;

        }
    }

    /**
     * @param uniqueValue 唯一字段对应的值
     * @return 删除是否成功
     */
    public boolean delete(Object uniqueValue) {
        //delete from user where username='zhangsan' AND password='1234653';
        int delete = mWritableDatabase.delete(TABLE_NAME, UNIQUE_FEILD + "=?", new String[]{String.valueOf(uniqueValue)});
        return delete != 0;
    }

    /**
     * 修改
     *
     * @param contentValues
     * @param uniqueValue
     * @return
     */
    public boolean update(ContentValues contentValues, Object uniqueValue) {
        if (!contentValues.containsKey(UNIQUE_FEILD)) {
            int update = mWritableDatabase.update(TABLE_NAME, contentValues, UNIQUE_FEILD + "=?", new String[]{String.valueOf(uniqueValue)});
            return update > 0;
        }
        Log.d(TAG, "update: 不能修改唯一值字段的值");
        return false;
    }


    /**
     * * 单条记录查询
     * 通过唯一值字段进行查询
     *
     * @param UNIQUE_Value 唯一键的值
     * @return
     */
    public UseDefine singleFind(Object UNIQUE_Value) {
        UseDefine singleData = null;
        Cursor cursor = mReadableDatabase.rawQuery("select * from " + TABLE_NAME + " where " + UNIQUE_FEILD + "=?", new String[]{String.valueOf(UNIQUE_Value)});
        while (cursor.moveToNext()) {
            singleData = getSingleData(cursor);
        }
        cursor.close();
        return singleData;
    }
}
